package Part4_反射的应用;

import Part4_反射的应用.data.Person;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * ClassName: Test
 * Package: IntelliJ IDEA
 * Description:
 * Written by HanXu
 * Create 2024.05.08 9:32
 */
public class Test {
    @org.junit.Test
    public void test1() throws InstantiationException, IllegalAccessException {
        Class<Person> personClass = Person.class;

        //Person实例的创建
        Person person1 = personClass.newInstance();
        //InstantiationException:无空参构造器的异常
        //IllegalAccessException:获取构造器权限不够的异常

        //getFields()只能获取类本身和其父类的public属性
        Field[] fields = personClass.getFields();
        for (Field field : fields){
            System.out.println(field);
        }

        //getFields()只能获取该类本身所有的属性
        Field[] declaredFields = personClass.getDeclaredFields();
        for (Field field : declaredFields){
            System.out.println(field);
        }
    }


    /**
     * 获取运行时类的父类
     * @throws ClassNotFoundException
     */
    @org.junit.Test
    public void test2() throws ClassNotFoundException {
        Class<?> personClass = Class.forName("Part4_反射的应用.data.Person");
        Class<?> superclass = personClass.getSuperclass();

        System.out.println(superclass);//Creature
    }


    /**
     * 获取运行时类带有泛型的父类
     * @throws ClassNotFoundException
     */
    @org.junit.Test
    public void test3() throws ClassNotFoundException {
        Class<?> personClass = Class.forName("Part4_反射的应用.data.Person");
        Type superClass = personClass.getGenericSuperclass();

        System.out.println(superClass);//Creature<java.lang.String>
    }

    /**
     * 获取运行时类带有的接口
     * @throws ClassNotFoundException
     */
    @org.junit.Test
    public void test4() throws ClassNotFoundException {
        Class<?> personClass = Class.forName("Part4_反射的应用.data.Person");
        Class<?>[] interfaces = personClass.getInterfaces();

        for(Class<?> c : interfaces){
            System.out.println(c);
        }
    }

    /**
     * 获取运行时类所在的包
     * @throws ClassNotFoundException
     */
    @org.junit.Test
    public void test5() throws ClassNotFoundException {
        Class<?> personClass = Class.forName("Part4_反射的应用.data.Person");
        Package classPackage = personClass.getPackage();

            System.out.println(classPackage);//Part4_反射的应用.data
    }

    /**
     * 获取运行时类的父类的泛型(难点 )
     * @throws ClassNotFoundException
     */
    @org.junit.Test
    public void test6() throws ClassNotFoundException {
        Class<?> personClass = Class.forName("Part4_反射的应用.data.Person");
        Type superClass = personClass.getGenericSuperclass();//Creature<String>

        /*
         * 转换成ParameterizedType后，就可以调用该接口提供的方法，如getActualTypeArguments()，来获取泛型参数的实际类型。
         * 如果不进行转换，你就无法访问这些特定于泛型的方法
         */
        ParameterizedType type = (ParameterizedType) superClass;

        //获取泛型参数类型的数组getActualTypeArguments()
        Type[] actualTypeArguments = type.getActualTypeArguments();
        System.out.println(actualTypeArguments[0].getTypeName());//java.lang.String

    }
}
